﻿using System;
using System.Collections;
using System.Collections.Generic;
using SFML.Window;

namespace Transformable_Engine_v2.Engine.Input
{
    public class KeyboardInput
    {
        public KeyboardInput(bool ctrl, bool alt, bool system, bool shift, Key code)
        {
            Ctrl = ctrl;
            Alt = alt;
            System = system;
            Shift = shift;
            KeyCode = code;
        }

        public bool Ctrl { get; set; }
        public bool Alt { get; set; }
        public bool System { get; set; }
        public bool Shift { get; set; }
        public Key KeyCode { get; set; }

        public enum Key
        {
            Unknown = -1,
            A = 0,
            B = 1,
            C = 2,
            D = 3,
            E = 4,
            F = 5,
            G = 6,
            H = 7,
            I = 8,
            J = 9,
            K = 10,
            L = 11,
            M = 12,
            N = 13,
            O = 14,
            P = 15,
            Q = 16,
            R = 17,
            S = 18,
            T = 19,
            U = 20,
            V = 21,
            W = 22,
            X = 23,
            Y = 24,
            Z = 25,
            Num0 = 26,
            Num1 = 27,
            Num2 = 28,
            Num3 = 29,
            Num4 = 30,
            Num5 = 31,
            Num6 = 32,
            Num7 = 33,
            Num8 = 34,
            Num9 = 35,
            Escape = 36,
            LControl = 37,
            LShift = 38,
            LAlt = 39,
            LSystem = 40,
            RControl = 41,
            RShift = 42,
            RAlt = 43,
            RSystem = 44,
            Menu = 45,
            LBracket = 46,
            RBracket = 47,
            SemiColon = 48,
            Comma = 49,
            Period = 50,
            Quote = 51,
            Slash = 52,
            BackSlash = 53,
            Tilde = 54,
            Equal = 55,
            Dash = 56,
            Space = 57,
            Enter = 58,
            Back = 59,
            Tab = 60,
            PageUp = 61,
            PageDown = 62,
            End = 63,
            Home = 64,
            Insert = 65,
            Delete = 66,
            Add = 67,
            Subtract = 68,
            Multiply = 69,
            Divide = 70,
            Left = 71,
            Right = 72,
            Up = 73,
            Down = 74,
            Numpad0 = 75,
            Numpad1 = 76,
            Numpad2 = 77,
            Numpad3 = 78,
            Numpad4 = 79,
            Numpad5 = 80,
            Numpad6 = 81,
            Numpad7 = 82,
            Numpad8 = 83,
            Numpad9 = 84,
            F1 = 85,
            F2 = 86,
            F3 = 87,
            F4 = 88,
            F5 = 89,
            F6 = 90,
            F7 = 91,
            F8 = 92,
            F9 = 93,
            F10 = 94,
            F11 = 95,
            F12 = 96,
            F13 = 97,
            F14 = 98,
            F15 = 99,
            Pause = 100,
            KeyCount = 101,
            GamepadButton0,
            GamepadButton1,
            GamepadButton2,
            GamepadButton3,
            GamepadButton4,
            GamepadButton5,
            GamepadButton6,
            GamepadButton7,
            GamepadButton8,
            GamepadButton9,
            GamepadButton10,
            JoystickX,
            JoystickY,
            JoystickZ,
            JoystickR,
            JoystickU,
            JoystickV,
            JoystickPovX,
            JoystickPovY,
            JoystickMX,
            JoystickMY,
            JoystickMZ,
            JoystickMR,
            JoystickMU,
            JoystickMV,
            JoystickPovMX,
            JoystickPovMY,
        }
    }

    public class KeyboardHandler
    {
        private static Queue _events = Queue.Synchronized(new Queue());

        public delegate void KeyboardInputHandler(KeyboardInput input);

        public static event KeyboardInputHandler OnKeyboardPress;
        public static event KeyboardInputHandler OnKeyboardReleased;

        public delegate void KeyboardTextHandler(string input);

        public static event KeyboardTextHandler OnWriteText;

        public static void OnKeyPress(object sender,
                                      KeyEventArgs eventArgs)
        {
            if (OnKeyboardPress != null)
            {
                Game.AddToEventQueue(() => OnKeyboardPress(new KeyboardInput(eventArgs.Control, eventArgs.Alt,
                                                    eventArgs.System, eventArgs.Shift,
                                                    (KeyboardInput.Key)eventArgs.Code)));
            }
        }

        public static void OnKeyReleased(object sender,
                                         KeyEventArgs eventArgs)
        {
            if (OnKeyboardReleased != null)
            {
                Game.AddToEventQueue(() => OnKeyboardReleased(new KeyboardInput(eventArgs.Control, eventArgs.Alt, 
                                                    eventArgs.System, eventArgs.Shift, 
                                                    (KeyboardInput.Key) eventArgs.Code)));
            }
                
        }

        public static void OnTextEntered(object sender, TextEventArgs e)
        {
            if (OnWriteText != null)
            {
                Game.AddToEventQueue(() => OnWriteText(e.Unicode));
            }
        }
    }
}